package com.mazaiting.instructions.control;

import com.mazaiting.instructions.base.NoOperandsInstruction;
import com.mazaiting.rtda.MtFrame;
import com.mazaiting.rtda.MtThread;
import com.mazaiting.rtda.heap.MtObject;

/**
 * 返回指令
 *
 * @author mazaiting
 * @since 2021/8/24
 */
public class ReturnInstruction {
    /**
     * 只要把当前帧从Java虚拟机栈中弹出即可
     */
    public static class Return extends NoOperandsInstruction {
        @Override
        public void execute(MtFrame frame) {
            frame.getThread().popFrame();
        }

        @Override
        public String toString() {
            return "return";
        }
    }

    /**
     * 只要把当前帧从Java虚拟机栈中弹出即可
     */
    public static class AReturn extends NoOperandsInstruction {
        @Override
        public void execute(MtFrame frame) {
            MtThread thread = frame.getThread();
            MtFrame currentFrame = thread.popFrame();
            MtFrame topFrame = thread.topFrame();
            MtObject value = currentFrame.getOperandStack().popRef();
            topFrame.getOperandStack().pushRef(value);
        }

        @Override
        public String toString() {
            return "areturn";
        }
    }

    /**
     * 只要把当前帧从Java虚拟机栈中弹出即可
     */
    public static class DReturn extends NoOperandsInstruction {
        @Override
        public void execute(MtFrame frame) {
            MtThread thread = frame.getThread();
            MtFrame currentFrame = thread.popFrame();
            MtFrame topFrame = thread.topFrame();
            double value = currentFrame.getOperandStack().popDouble();
            topFrame.getOperandStack().pushDouble(value);
        }

        @Override
        public String toString() {
            return "dreturn";
        }
    }

    /**
     * 只要把当前帧从Java虚拟机栈中弹出即可
     */
    public static class FReturn extends NoOperandsInstruction {
        @Override
        public void execute(MtFrame frame) {
            MtThread thread = frame.getThread();
            MtFrame currentFrame = thread.popFrame();
            MtFrame topFrame = thread.topFrame();
            float value = currentFrame.getOperandStack().popFloat();
            topFrame.getOperandStack().pushFloat(value);
        }

        @Override
        public String toString() {
            return "freturn";
        }
    }

    /**
     * 只要把当前帧从Java虚拟机栈中弹出即可
     */
    public static class IReturn extends NoOperandsInstruction {
        @Override
        public void execute(MtFrame frame) {
            MtThread thread = frame.getThread();
            MtFrame currentFrame = thread.popFrame();
            MtFrame topFrame = thread.topFrame();
            int value = currentFrame.getOperandStack().popInt();
            topFrame.getOperandStack().pushInt(value);
        }

        @Override
        public String toString() {
            return "ireturn";
        }
    }

    /**
     * 只要把当前帧从Java虚拟机栈中弹出即可
     */
    public static class LReturn extends NoOperandsInstruction {
        @Override
        public void execute(MtFrame frame) {
            MtThread thread = frame.getThread();
            MtFrame currentFrame = thread.popFrame();
            MtFrame topFrame = thread.topFrame();
            long value = currentFrame.getOperandStack().popLong();
            topFrame.getOperandStack().pushLong(value);
        }

        @Override
        public String toString() {
            return "lreturn";
        }
    }
}

